package com.zecan.blog.service.impl;

import com.zecan.blog.common.status.UserStatus;
import com.zecan.blog.controller.exception.UserException;
import com.zecan.blog.dao.FollowMapper;
import com.zecan.blog.dto.follow.FollowDto;
import com.zecan.blog.rabbitmq.BlogMqProducer;
import com.zecan.blog.rabbitmq.event.FollowEvent;
import com.zecan.blog.service.FollowService;
import com.zecan.blog.utils.BlogConstant;
import com.zecan.blog.utils.RedisUtils;
import com.zecan.blog.utils.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class FollowServiceImpl implements FollowService {
    @Resource
    private FollowMapper followMapper;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private BlogMqProducer blogMqProducer;

    public FollowServiceImpl() {
    }

    public void  addFollow(FollowDto followDto) {
        Integer followUserId = followDto.getFollowUserId();
        Integer followerUserId = followDto.getFollowerUserId();
        String followUserAvatar = followDto.getFollowUserAvatar();
        String followerUserAvatar = followDto.getFollowerUserAvatar();
        Integer followStatus = null;
        // 判断当前redis中是否存放关注信息，且数据库中是否有关注信息 如果没有则报错
        if (redisUtils.hasHashKey(StringUtils.concatRedisViewKey(followUserId), StringUtils.concatRedisViewHashKey(followUserId, followerUserId))) {
            followStatus = followMapper.findFollowById(followUserId, followerUserId);
            // 如果此时有关注信息 且数据库中没有关注 则有异常
            if (followStatus.equals(0)) {
                throw new UserException(UserStatus.USER_FOLLOW_IS_EXIST);
                //TODO : 有异常应该要处理..... 忘记了
            }
        }
        // == null 说明redis不存在信息
        if(followStatus == null) {
            followStatus = followMapper.findFollowById(followUserId, followerUserId);
        }
        FollowEvent followEvent;
        // 如果当前不为null 且 之前取消过关注
        if (followStatus != null && followStatus.equals(1)) {
            // 进行数据的整合, 交给Rabbitmq进行关注 如果之前取消过关注 则进行修改即可
            followEvent = FollowEvent.builder().followerUserAvatar(followerUserAvatar)
                    .followUserAvatar(followUserAvatar).followUserId(followUserId)
                    .isFirst(false).followerUserId(followerUserId).build();
            blogMqProducer.sendFollowMessage(BlogConstant.RABBITMQ_EXCHANGE, BlogConstant.RABBITMQ_FOLLOW_ROUTING_KEY, followEvent);
        } else {
            // 如果没有进行关注 则需要插入数据 isFirst = true
            followEvent = FollowEvent.builder().followerUserAvatar(followerUserAvatar)
                    .followUserAvatar(followUserAvatar).followUserId(followUserId)
                    .isFirst(true).followerUserId(followerUserId).build();
            blogMqProducer.sendFollowMessage(BlogConstant.RABBITMQ_EXCHANGE, BlogConstant.RABBITMQ_FOLLOW_ROUTING_KEY, followEvent);
        }
    }

    public void unFollow(FollowDto followDto) {
        Integer followUserId = followDto.getFollowUserId();
        Integer followerUserId = followDto.getFollowerUserId();
        String followUserAvatar = followDto.getFollowUserAvatar();
        String followerUserAvatar = followDto.getFollowerUserAvatar();
        Integer followStatus = null;
        // 判断当前是否有关注信息在redis中
        if (!redisUtils.hasHashKey(StringUtils.concatRedisViewKey(followUserId), StringUtils.concatRedisViewHashKey(followUserId, followerUserId))) {
            followStatus = followMapper.findFollowById(followUserId, followerUserId);
            if (followStatus != null && followStatus.equals(1)) {
                throw new UserException(UserStatus.USER_IS_NOT_FOLLOW);
                // TODO 有数据异常 需进行排查
            }
        }
        // 添加取消关注消息队列
        FollowEvent followEvent = FollowEvent.builder().followerUserAvatar(followerUserAvatar)
                .followUserAvatar(followUserAvatar)
                .followUserId(followUserId).followerUserId(followerUserId).build();
        // 交给Rabbitmq进行处理
        blogMqProducer.sendUnFollowMessage(BlogConstant.RABBITMQ_EXCHANGE, BlogConstant.RABBITMQ_UNFOLLOW_ROUTING_KEY, followEvent);
    }
}